﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Web.UI;
using Succell.Dnn.JQuery.UI;

namespace Succell.Dnn.JQuery.Extras
{
    /// <summary>
    /// Adds a watermark to the targeted control(s).
    /// </summary>
    public class WatermarkExtender : Control
    {
        #region properties

        /// <summary>
        /// Gets or sets the selector for targeting controls to be extended with the
        /// <see cref="WatermarkExtender"/>.
        /// </summary>
        [Browsable(true)]
        [Localizable(false)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        [Category("Behavior")]
        public string Selector { get; set; }

        #endregion

        #region jQuery UI settings properties

        private string watermarkText = String.Empty;

        /// <summary>
        /// Gets or sets the text to display as a watermark for the control.
        /// </summary>
        [Setting("watermarkText")]
        [Browsable(true)]
        [Localizable(false)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        [Category("Appearance")]
        [DefaultValue("")]
        public string WatermarkText
        {
            get { return this.watermarkText; }
            set { this.watermarkText = value ?? String.Empty; }
        }

        private string watermarkCssClass = "watermark";

        /// <summary>
        /// Gets or sets the css class to add to the watermarked control.
        /// </summary>
        [Setting("watermarkClass")]
        [Browsable(true)]
        [Localizable(false)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        [Category("Appearance")]
        [DefaultValue("watermark")]
        public string WatermarkCssClass
        {
            get { return this.watermarkCssClass; }
            set { this.watermarkCssClass = value ?? String.Empty; }
        }

        private WatermarkEvent @event = WatermarkEvent.Focus;

        /// <summary>
        /// Gets or sets whether the watermark logic will be fired when the targeted control
        /// gets and loses focus or when a user types in the targeted control.
        /// </summary>
        [Setting("event")]
        [Browsable(true)]
        [Localizable(false)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        [Category("Behavior")]
        [DefaultValue(WatermarkEvent.Focus)]
        public WatermarkEvent Event
        {
            get { return this.@event; }
            set { this.@event = value; }
        }

        #endregion

        #region events

        /// <summary>
        /// This event is raised, just before the control applies its javascript
        /// settings to the initialization code. You can use it to manipulate the
        /// settings dictionary.
        /// </summary>
        /// <remarks>
        /// Be careful when using this event. It allows you to reach deeply into
        /// the internal workings of the control, possibly breaking functionality.
        /// </remarks>
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        [Localizable(false)]
        [Category("Behavior")]
        public event EventHandler<SettingsEventArgs> ApplyingSettings;

        /// <summary>
        /// Fires the <see cref="ApplyingSettings"/> event.
        /// </summary>
        /// <param name="e">The <see cref="SettingsEventArgs"/> passed to the event.</param>
        protected virtual void OnApplyingSettings(SettingsEventArgs e)
        {
            if (null != this.ApplyingSettings)
            {
                this.ApplyingSettings(this, e);
            }
        }

        #endregion

        #region page lifecycle

        protected override void OnInit(EventArgs e)
        {
            this.Page.RegisterJQueryUI();

            base.OnInit(e);
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (this.Visible && !String.IsNullOrEmpty(this.Selector))
            {
                var settings = SettingSerializer.FetchSettings(this);
                // apply custom setting manipulation logic
                this.OnApplyingSettings(new SettingsEventArgs(settings));
                string settingsJson = SettingSerializer.Serialize(settings);
                this.Page.ClientScript.RegisterClientScriptInclude(typeof (WatermarkExtender), "jquery-ui.watermark",
                                                                   this.ResolveUrl(
                                                                       "~/DesktopModules/Succell.JQuery.Extras/js/jquery-ui.watermark.0.5.0.min.js"));
                this.Page.RegisterJQueryOnDocumentReadyBlock(
                    String.Format(
                        CultureInfo.InvariantCulture,
                        "$('{0}').watermark({1})",
                        this.Selector,
                        settingsJson));
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
        }

        #endregion
    }
}